CSS - 定位模型

position 属性定义建立元素布局所用的定位机制。任何元素都可以定位,不过绝对或固定元素会生成一个块级框,而不论该元素本身是什么类型。相对定位元素会相对于它在正常流中的默认位置偏移。position 属性有以下几种模型:

  • static 自然模型
  • relative 相对定位模型
  • absolute 绝对定位模型
  • fixed 固定定位模型
  • sticky 磁贴定位模型

在学习布局模型之前,我们先来了解几个属性。

z-index

z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。元素可拥有负的 z-index 属性值。仅能在定位元素,例如 position:absolute 这样的元素上奏效!

该属性设置一个定位元素沿 z 轴的位置,z 轴定义为垂直延伸到显示区的轴。如果为正数,则离用户更近,为负数则表示离用户更远。

描述
auto 默认。堆叠顺序与父元素相等。
number 设置元素的堆叠顺序。
inherit 规定应该从父元素继承 z-index 属性的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
<style type="text/css">
img.x {
position: absolute;
left: 0px;
top: 0px;
z-index: -1;
}
</style>
</head>
<body>
<h1>这是一个标题</h1>
<img class="x" src="http://www.w3school.com.cn/i/eg_mouse.jpg" />
<p>默认的 z-index 是 0。Z-index -1 拥有更低的优先级。</p>
</body>
</html>

在这个例子中,img 原本应该在 p 元素的上面,但是由于修改了 imgz-index 属性,因此 p 显示在了 img 的上面。

static 自然定位

static 的叫法有很多,如静态定位,常规定位,自然定位等。特点如下:

  1. 使元素定位于常规/自然流中,也就是块、行垂直排列下去,行内元素水平从左往右排列;
  2. 忽略 top、bottom、left、right 或者 z-index 声明;
  3. 两个相邻的元素如果都设置了 margin,那么最终外边距会取两者中最大的;
  4. 如果是具有固定的 width、height 属性,如果将左右外边距设置为 auto,则左右外边距会自动扩大占满剩余宽度,最终的效果是这个块水平居中。

relative 相对定位

relative 作用是使元素成为可定位的祖先元素,通俗的讲,就是可以使其他元素以此元素作为参照物设定坐标。relative 有以下几个特点:

  1. 可以使用 top、bottom、right、left、z-index 等属性进行相对定位,这里的相对定位参展的是此元素在自然流中原本的位置;

  2. 相对定位的元素不会离开常规流,也就是说使用 top、bottom、right、left、z-index 等属性设定偏移后,自然流中依然保留此元素的位置;

  3. 任何元素都可以设置为 relation,它的绝对定位的后代都可以相对于它进行绝对定位,这点在网页广告中应用较多,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title></title>
    <style media="screen
    .parent {
    width: 200px;
    height: 150px;
    border: 1px solid #000;
    position: relative;
    }
    .child {
    width: 80px;
    height: 80px;
    background-color: blue;
    position: absolute;
    right: -80px;
    top: 0;
    }
    </style>
    </head>
    <body>
    <div class="parent">
    <div class="child">
    </div>
    </div>
    </body>
    </html>
  4. 可以使浮动元素发生偏移,并控制它们的堆叠顺序。这句话怎么理解呢?通常在浮动元素中,我们无法修改元素的偏移,但使用 relation 后,就可以通过 top、bottom、right、left 进行偏移了,同理,也可以通过 z-index 来改变堆叠顺序。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title></title>
    <style media="screen">
    .block {
    width: 50px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    border: 1px solid #000;
    float: left;
    }
    .block:nth-child(2) {
    /*改变浮动元素的位置*/
    position: relative;
    top: 10em;
    /*margin-top: 10px;*/
    }
    /*改变浮动元素的层级*/
    .block:nth-child(4) {
    z-index: 9
    }
    .block:nth-child(5) {
    position: relative;
    border: 1px solid red;
    left: -52px;
    z-index: 20;
    }
    </style>
    </head>
    <body>
    <div class="block">A</div>
    <div class="block">B</div>
    <div class="block">C</div>
    <div class="block">D</div>
    <div class="block">E</div>
    <div class="block">F</div>
    </body>
    </html>

absolute 绝对定位

absolute 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。位置通过 left、top、right、bottom 属性进行规定,absolute 有以下特性:

  1. 使元素脱离常规流,也就是说自然流中不会再保存此元素的位置,此处需要注意的是,如果使用 % 作为单位进行偏移,这个 % 对比的是最近的祖先元素;

  2. 如果有父级元素中有 relative ,那么这个标签就是此元素的祖先元素,如果没有,那么 <body> 就是此元素的祖先元素;

  3. right、left、top、bottom 等值如果设置为 0px,它将对齐到最近的祖先元素的各边,这种特性可以用来设定居中对齐,需要注意的是,如果此元素没有设定宽高,实际上和 width: 100%; height: 100%; 是一个意思;如果设定了宽高,可以使用以下方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .child {
    background-color: blue;
    position: absolute;
    width: 100px;
    height: 100px;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto auto;
    }
  4. right、left、top、bottom 等值如果设置为 auto,那么它会回到常规流中;

fixed 固定定位

absolutefixed 都是用于绝对定位,两者不同之处在以下几点:

  1. absolute 相对于最近的祖先元素进行绝对定位,而 fixed 是相对于浏览器的窗口进行定位,这个特点使得 fixed 适合用于悬浮效果;
  2. 固定定位元素不会随着浏览器窗口的滚动而滚动;

sticky 磁贴定位

sticky 也有很多名字,比如磁贴定位、粘性定位、吸附定位等,sticky 只适用于 CSS3 版本。sticky 类似 relativefixed 的结合体,使用 sticky 可以很轻松的做出元素到达浏览器顶部后悬浮的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style media="screen">
* {
padding: 0;
margin: 0;
}
.header {
background-color: red;
height: 50px;
}
.nav {
background-color: blue;
height: 50px;
width: 100%;
position: sticky;
top: 0;
}
</style>
</head>
<body>
<div class="header">
这里是 logo
</div>
<div class="nav">
这里是导航,有分享,收藏,登录,喜欢等等
</div>
<div class="">
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</body>
</html>

sticky 有以下几个特性:

  1. 如果产生偏移,原位置依然还会在常规流中;

  2. 如果它的祖先元素有滚动,那么它的偏移标尺就是最近的祖先元素,这个改怎么理解呢?如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title></title>
    <style media="screen">
    * {
    padding: 0;
    margin: 0;
    }
    .header {
    background-color: red;
    height: 50px;
    }
    .nav {
    background-color: blue;
    height: 50px;
    width: 100%;
    position: sticky;
    top: 0;
    }
    .top {
    background-color: yellow;
    height: 70px;
    width: 100%;
    }
    .content {
    height: 300px;
    position: relative;
    overflow: scroll;
    }
    </style>
    </head>
    <body>
    <div class="header">
    这里是 logo
    </div>
    <div class="content">
    <div class="top">
    这里是一些内容
    </div>
    <div class="nav">
    这里是导航,有分享,收藏,登录,喜欢等等
    </div>
    <div class="">
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    </div>
    </div>
    <div class="">
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    </div>
    </body>
    </html>

    此时,sticky 的父级元素是有滚动的,因此它的偏移标尺是父级元素,因此滚动第二层的下拉框,会触发悬浮,滚动第一次则无效果;

  3. 如果祖先元素没有滚动,那么它的偏移标尺就是浏览器的窗口;